package com.push.mq.utils;

import android.content.Context;
import android.os.Environment;
import android.os.StatFs;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.util.Log;

import com.loyal.kit.IOUtil;
import com.loyal.kit.TimeUtil;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class FileUtil extends com.loyal.kit.FileUtil {

    // sd卡路径
    public static final String SD_PATH = Environment.getExternalStorageDirectory().getPath();
    public static final String MAIN_PATH = SD_PATH + "/com.inspect.record/";
    // apk更新下载的更新文件存放的目录
    public static final String apkPath = MAIN_PATH + "apk/";
    public static final String logPath = MAIN_PATH + "log/";
    // video存放地址
    public static final String videoPath = MAIN_PATH + "video/";
    public static final String datePath = String.format("%s%s/", videoPath, TimeUtil.getDate("yyyyMMdd"));
    public static final String apkName = "inspectRecord.apk";

    private static String[] paths = new String[]{apkPath, logPath, datePath, videoPath};

    // 创建文件夹是否成功
    public static void createFileSys() {
        for (String path : paths) {
            File file = new File(path);
            mkDirs(file);
        }
    }

    public static void deleteEmptyDirs(File file) {
        if (file.isDirectory()) {
            File[] childFiles = file.listFiles();
            if (childFiles == null || childFiles.length == 0) {
                deleteFile(file);
            } else {
                for (File f : childFiles) {
                    deleteEmptyDirs(f);
                }
            }
        }
    }

    public static void deleteEmptyDirs(String dirPath) {
        deleteEmptyDirs(new File(dirPath));
    }

    /**
     * 文件和文件夹一起删除
     */
    public static boolean deleteDirs(File file) {
        if (file.isDirectory()) {
            File[] childFiles = file.listFiles();
            if (childFiles == null || childFiles.length == 0) {
                return false;
            }
            for (File f : childFiles) {
                deleteDirs(f);
            }
        }
        return file.exists() && file.delete();
    }

    public static String getTotal(Context context) {
        try {
            StatFs fs = new StatFs(SD_PATH);
            //可用的blocks的数量

            long blockSize = fs.getBlockSize();
            long totalBlocks = fs.getBlockCount();
            long total = totalBlocks * blockSize;
            String format = Formatter.formatFileSize(context, total);
            if (TextUtils.isEmpty(format)) {
                return "0";
            }
            return format.substring(0, format.indexOf("."));
        } catch (Exception e) {
            return "0";
        }
    }

    public static void deleteFileWithDir(File file) {
        if (file.exists()) { //指定文件是否存在
            if (file.isFile()) { //该路径名表示的文件是否是一个标准文件
                deleteFile(file); //删除该文件
            } else if (file.isDirectory()) { //该路径名表示的文件是否是一个目录（文件夹）
                File[] files = file.listFiles(); //列出当前文件夹下的所有文件
                for (File f : files) {
                    deleteFileWithDir(f); //递归删除
                    //Log.d("fileName", f.getName()); //打印文件名
                }
            }
            deleteFile(file);
            //删除文件夹（song,art,lyric）
        }
    }

    // 保存IP文件到本地 这里只需要把文件名传进去就行，不管保存的类型
    public static void createFile(String path, String fileName, String content) {
        File file = new File(path, fileName);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(content.getBytes());
            fos.flush();
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String createFileName(String name, String extension) {
        // 查看是否带"."
        try {
            if (!extension.startsWith("."))
                extension = "." + extension;
            return name + extension;
        } catch (Exception e) {
            return "";
        }
    }

    // @ 读取文件中的内容
    public static String readFileContent(String path, String fileName) {
        File file = new File(new File(path), fileName);
        try {
            BufferedReader br;
            StringBuilder sb = new StringBuilder();
            br = new BufferedReader(new FileReader(file));
            String readLine;
            while ((readLine = br.readLine()) != null) {
                sb.append(readLine);
            }
            br.close();
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    public static boolean upZipFile(String zipFile, String folderPath) {
        ZipFile zfile;
        try {
            // 转码为GBK格式，支持中文
            zfile = new ZipFile(zipFile);
            Enumeration zList = zfile.entries();
            ZipEntry ze;
            byte[] buf = new byte[1024];
            while (zList.hasMoreElements()) {
                ze = (ZipEntry) zList.nextElement();
                // 列举的压缩文件里面的各个文件，判断是否为目录
                if (ze.isDirectory()) {
                    String dirstr = (folderPath + ze.getName()).trim();
                    File file = new File(dirstr);
                    file.mkdir();
                    continue;
                }
                OutputStream os = null;
                // ze.getName()会返回 script/start.script这样的，是为了返回实体的File
                File realFile = getRealFileName(folderPath, ze.getName());
                InputStream is = null;
                FileOutputStream fos = new FileOutputStream(realFile);
                os = new BufferedOutputStream(fos);
                is = new BufferedInputStream(zfile.getInputStream(ze));
                int readLen;
                // 进行一些内容复制操作
                while ((readLen = is.read(buf, 0, 1024)) != -1) {
                    os.write(buf, 0, readLen);
                }
                IOUtil.closeStream(is);
                IOUtil.closeStream(os);
            }
            zfile.close();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 给定根目录，返回一个相对路径所对应的实际文件名.
     *
     * @param baseDir     指定根目录
     * @param absFileName 相对路径名，来自于ZipEntry中的name
     * @return java.io.File 实际的文件
     */
    public static File getRealFileName(String baseDir, String absFileName) {
        absFileName = absFileName.replace("\\", "/");
        String[] dirs = absFileName.split("/");
        File ret = new File(baseDir);
        String substr;
        if (dirs.length > 1) {
            for (int i = 0; i < dirs.length - 1; i++) {
                substr = dirs[i];
                ret = new File(ret, substr);
            }
            mkDirs(ret);
            substr = dirs[dirs.length - 1];
            ret = new File(ret, substr);
            return ret;
        } else {
            ret = new File(ret, absFileName);
        }
        return ret;
    }
    /*//硬件制造商（MANUFACTURER）
        String manufacturer = Build.MANUFACTURER;
        System.out.println("硬件制造商==" + manufacturer);
        //品牌名称（BRAND）
        String brand = Build.BRAND;
        System.out.println("品牌名称==" + brand);
        //主板名称（BOARD）
        String board = Build.BOARD;
        System.out.println("主板名称==" + board);
        //设备名 （DEVICE）
        String device = Build.DEVICE;
        System.out.println("设备名==" + device);
        //型号（MODEL）:即用户可见的名称
        String model = Build.MODEL;
        System.out.println("型号==" + model);
        //显示屏参数（DISPLAY）
        String display = Build.DISPLAY;
        System.out.println("显示屏参数==" + display);
        //产品名称（PRODUCT）：即手机厂商
        String product = Build.PRODUCT;
        System.out.println("产品名称==" + product);
        //设备唯一识别码（FINGERPRINT）
        String fingerprint = Build.FINGERPRINT;
        System.out.println("设备唯一识别码==" + fingerprint);
        //CPU指令集（CPU_ABI）
        String productABI = Build.CPU_ABI;
        System.out.println("CPU指令集==" + productABI);
        //CPU指令集2（CPU_ABI2）
        String product_ABI2 = Build.CPU_ABI2;
        System.out.println("CPU指令集2==" + product_ABI2);
        //修订版本列表（ID）
        String id = Build.ID;
        System.out.println("修订版本列表==" + id);
        //描述build的标签（TAGS）
        String tags = Build.TAGS;
        System.out.println("描述build的标签==" + tags);*/

    public static void saveCrashInfo(String fileName, Throwable ex) {
        StringBuilder sb = new StringBuilder();
        Writer writer = new StringWriter();
        PrintWriter printWriter = new PrintWriter(writer);
        ex.printStackTrace(printWriter);
        Throwable cause = ex.getCause();
        while (cause != null) {
            cause.printStackTrace(printWriter);
            cause = cause.getCause();
        }
        printWriter.close();
        String result = writer.toString();
        sb.append(result);
        try {
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                String path = FileUtil.logPath;
                File dir = new File(path);
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                FileOutputStream fos = new FileOutputStream(new File(path, fileName));
                fos.write(sb.toString().getBytes());
                fos.close();
            }
        } catch (Exception e) {
            Log.e("", "an error occured while writing file...", e);
        }
    }
}
